package com.echat.commonlib.exception;

import com.echat.commonlib.bean.HttpResult;
import com.echat.commonlib.constant.ErrorCode;
import com.echat.commonlib.exception.exc.BussinessException;
import com.echat.commonlib.exception.exc.EchatSecurityException;
import com.echat.commonlib.exception.exc.ValidateFailedException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * Created by chenmohan on 2018/08/30
 *
 * @description
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionProcessor {

    /**
     * SpringMVC将404包装成异常，这里捕获404异常
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    public void catchNoHandlerFoundException(HttpServletRequest request, HttpServletResponse response, NoHandlerFoundException e) throws ServletException, IOException {
        request.getRequestDispatcher("/errorWithJson?code=" + ErrorCode.NOT_FOUND_404 + "&msg=" + "[404 not found] " + e.getMessage()).forward(request, response);
    }

    @ExceptionHandler(ValidateFailedException.class)
    @ResponseBody
    public HttpResult catchValidateFailedException(HttpServletRequest request, HttpServletResponse response, ValidateFailedException e) throws ServletException, IOException {
        return HttpResult.failed(e.getCode(), e.getMessage());
        // request.getRequestDispatcher("/errorWithJson?code=" + e.getCode() + "&msg=" + e.getMessage()).forward(request, response);
    }

    @ExceptionHandler(BussinessException.class)
    public void catchBussinessException(HttpServletRequest request, HttpServletResponse response, BussinessException e) throws ServletException, IOException {
        request.getRequestDispatcher("/errorWithJson?code=" + ErrorCode.DEFAULT_BUSSINESS_FAILED + "&msg=" + e.getMessage()).forward(request, response);
    }

    @ExceptionHandler(EchatSecurityException.class)
    public void catchEchatSecurityException(HttpServletRequest request, HttpServletResponse response, EchatSecurityException e) throws ServletException, IOException {
        //如果是未登录,则跳转到登录页面
        if (e.getCode().equals(ErrorCode.NOT_LOGIN)) {
            response.sendRedirect("/admin/login.html");
            return;
        }
        request.getRequestDispatcher("/errorWithJson?code=" + e.getCode() + "&msg=" + e.getMessage()).forward(request, response);
    }

    /**
     * 捕获所有未知异常
     */
    @ExceptionHandler(Exception.class)
    public void catchException(HttpServletRequest request, HttpServletResponse response, Exception e) throws ServletException, IOException {
        log.error("trance:" + getErrorInfoFromException(e));
        request.getRequestDispatcher("/errorWithJson?code=" + 500 + "&msg=" + e.getMessage()).forward(request, response);
    }

    private static String getErrorInfoFromException(Exception e) {
        try {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            return "\r\n" + sw.toString() + "\r\n";
        } catch (Exception e2) {
            return "bad getErrorInfoFromException";
        }
    }
}
